package cn.vawn.base.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public final class NumberUtil {
    public static final String NUMBER = "#,##0.00";

    public static String formatNumber(double num) {
        Number number = new Double(num);
        return formatNumber(number, NUMBER);
    }

    public static String formatNumber(Number number, String pattern) {
        if (pattern == null)
            pattern = NUMBER;

        NumberFormat nf = new DecimalFormat(pattern);
        return nf.format(number);
    }

    public static boolean isIn(int[] nums, int num) {
        if (nums != null && nums.length > 0) {
            for (int i : nums) {
                if (num == i)
                    return true;
            }
        }

        return false;
    }

    public static boolean isOdd(int n) {
        return !(n % 2 == 0);
    }

    public static boolean isPrime(int n) {
        //check if n is a multiple of 2
        if (n % 2 == 0)
            return false;

        //if not, then just check the odds
        for (int i = 3; i * i <= n; i += 2) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

    public static int getOddCount(int[] ns) {
        if (ns == null || ns.length == 0)
            return 0;

        int count = 0;
        for (int n : ns) {
            if (isOdd(n)) {
                count++;
            }
        }
        return count;
    }

    public static int getLargeCount(int[] nums, int delimiter) {
        if (nums == null || nums.length == 0)
            return 0;

        int count = 0;
        for (int num : nums) {
            if (num >= delimiter) {
                count++;
            }
        }
        return count;
    }

    public static int getPrimeCount(int[] ns) {
        if (ns == null || ns.length == 0)
            return 0;

        int count = 0;
        for (int n : ns) {
            if (isPrime(n)) {
                count++;
            }
        }
        return count;
    }

    public static boolean isConsecutiveNums(int[] nums, int length) {
        if (nums == null || nums.length == 0)
            return false;

        int current = 0;
        boolean isConSeq = false;
        int previous = nums[0];
        int numSeqCount = 1;

        for (int i = 1; i < nums.length; i++) {
            current = nums[i];
            if ((previous + 1) == current) {
                numSeqCount++;
                if (numSeqCount >= length) {
                    isConSeq = true;
                    break;
                }
            } else {
                numSeqCount = 1;
            }
            previous = current;
        }
        return isConSeq;
    }

    public static Integer[] toIntegerArray(int[] ints) {
        if (ints == null || ints.length == 0)
            return null;

        Integer[] bigInts = new Integer[ints.length];
        for (int i = 0; i < ints.length; i++) {
            bigInts[i] = new Integer(ints[i]);
        }
        return bigInts;
    }

    public static int[] toIntArray(Integer[] bigInts) {
        if (bigInts == null || bigInts.length == 0)
            return null;

        int[] ints = new int[bigInts.length];
        for (int i = 0; i < bigInts.length; i++) {
            ints[i] = bigInts[i].intValue();
        }
        return ints;
    }

    public static int[] toIntArray(List<Integer> bigInts) {
        if (bigInts == null || bigInts.size() == 0)
            return null;

        int[] ints = new int[bigInts.size()];
        for (int i = 0; i < bigInts.size(); i++) {
            ints[i] = bigInts.get(i).intValue();
        }
        return ints;
    }

    public static int[] findDuplicatedNums(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0)
            return null;

        List<Integer> nums = new ArrayList<Integer>();
        for (int num1 : nums1) {
            for (int num2 : nums2) {
                if (num1 == num2) {
                    nums.add(num1);
                }
            }
        }
        if (nums.size() > 0)
            return toIntArray(nums);

        return null;
    }

    public static void sortNums(int[] nums) {
        if (nums != null) {
            Arrays.sort(nums);
        }
        //Arrays.asList(nums);
    }

    public static double roundNumber(double num, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }

        BigDecimal b = new BigDecimal(Double.toString(num));
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    private NumberUtil() {
    }
}
